package top.callback.inf.beautyleaf.server.common;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 控制器切面，包装异常信息
 *
 * @author Pengyu Gan
 * CreateDate 2021/3/30
 */
@Slf4j
@Aspect
@Component
public class LeafResultAOP {

    /**
     * 切入点，所有以 {@link LeafResult} 作为返回值的控制器方法
     */
    @Pointcut("execution(public top.callback.inf.beautyleaf.server.common.LeafResult *(..))")
    public void execute() {

    }

    /**
     * 切面逻辑
     * @param pjp {@link ProceedingJoinPoint} 切点上下文
     * @return {@link LeafResult} 请求响应数据模型
     */
    @Around("execute()")
    public Object handlerControllerMethod(ProceedingJoinPoint pjp) {
        LeafResult<?> result;
        StopWatch stopWatch = new StopWatch();
        try {
            result = (LeafResult<?>) pjp.proceed();
            long checkElapse = stopWatch.getElapse();
            log.info("{} cost time {} ms (check cost {} ms)", pjp.getSignature(), stopWatch.getElapse(), checkElapse);
        } catch (Throwable e) { // 处理异常
            result = handlerException(pjp, e);
        }
        return result;
    }

    /**
     * 请求出现异常的处理控制
     * @param pjp {@link ProceedingJoinPoint} 切点上下文
     * @param e {@link Throwable} 异常信息
     * @return {@link LeafResult} 请求响应数据模型
     */
    private LeafResult<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
        return LeafResult.error(e.getMessage());
    }

}
